import React, { forwardRef, useImperativeHandle, useMemo, useCallback } from "react";
import { Form, Input, TextArea, DatePicker, Button } from "antd-mobile";
import InputNumber from "rc-input-number";
import { Selector, PactSelector, WbsSelector, OrgSelector } from "pages/components/selector";
import PropTypes from "prop-types";
import dayjs from "dayjs";

const FormLayout = forwardRef((props, ref) => {
    const {
        subtitle,
        formItems,
        projId,
        pactId,
        selectCallBack, //后续可不使用，通过onValuesChange事件触发
        children,
        status,
        initSelect,
        state,
        formDisabled,
        onValuesChange,
        ...restProps
    } = props;
    const [form] = Form.useForm();

    const FormList = useMemo(() => {
        return formItems?.filter(item => item.name !== "standSubTable") || [];
    }, [props.formItems]);

    useImperativeHandle(ref, () => ({
        form,
    }));

    return (
        <div className="form-container">
            <Form name="form" form={form} disabled={formDisabled} onValuesChange={onValuesChange}>
                <Form.Header>{subtitle}</Form.Header>
                {FormList.map(({ label, name, required, hidden, disabled, ...rest }, i) => {
                    let formProps = {
                        label,
                        name,
                        rules: !hidden && required ? [{ required }] : null,
                    };

                    if (rest.type === "date") {
                        formProps = {
                            ...formProps,
                            trigger: "onConfirm",
                            onClick: (e, datePickerRef) => {
                                datePickerRef.current?.open();
                            },
                        };
                    }

                    const Component = getComponent({
                        ...rest,
                        ...restProps,
                        projId,
                        pactId,
                        selectCallBack,
                        initSelect,
                        status,
                        name,
                        hidden,
                    });

                    if (!Component) return null;

                    let fItemDisabled = formDisabled;
                    if (disabled) {
                        fItemDisabled = new Function(
                            "state",
                            "with(state){return " + disabled + ";}",
                        )(state);
                    }
                    return (
                        <Form.Item key={i} {...formProps} hidden={hidden} disabled={fItemDisabled}>
                            {Component}
                        </Form.Item>
                    );
                })}
            </Form>
            {children}
        </div>
    );
});

const getComponent = cProps => {
    const {
        type,
        props,
        name,
        projId,
        pactId,
        selectPact,
        selectCallBack,
        initSelect,
        status,
        hidden,
    } = cProps;
    switch (type) {
        case "input":
            if (props?.type === "textarea") {
                return <TextArea autoSize={true} />;
            }
            if (props?.type === "number") {
                return <InputNumber precision={props?.precision || 0} />;
            }
            return <Input />;
        case "date":
            return (
                <DatePicker precision={props?.precision || "day"}>
                    {value =>
                        value ? dayjs(value).format(props?.format || "YYYY-MM-DD") : "请选择日期"
                    }
                </DatePicker>
            );
        case "select":
            const Component = selectComponent[props.type]?.component;
            if (Component) {
                let fields = {};
                selectComponent[props.type].fields.forEach(field => {
                    fields[field] = props[field] || cProps[field]; //值优先取配置字段默认值    否则取父组件传递值
                });
                return (
                    <Component
                        {...fields}
                        fieldProps={props}
                        selectCallBack={selectCallBack}
                        initSelect={initSelect}
                        changeField={props.changeField}
                        name={name}
                        hidden={hidden}
                        editabled={props?.editabled}
                    />
                );
            } else {
                return (
                    <Selector
                        data={cProps[props?.optionsName]}
                        fieldProps={props}
                        selectCallBack={selectCallBack}
                        initSelect={initSelect}
                        changeField={props.changeField}
                        name={name}
                        hidden={hidden}
                        editabled={props?.editabled}
                    />
                );
            }

        default:
            return null;
    }
};

const selectComponent = {
    selectPact: {
        component: PactSelector,
        fields: ["projId", "pactId", "pactType"], //传递到组件字段
    },
    selectWbs: {
        component: WbsSelector,
        fields: ["projId", "pactId", "pactCode", "pactType"],
    },
    selectOrg: {
        component: OrgSelector,
        fields: ["projId", "pactId", "pactCode", "pactType"],
    },
};

FormLayout.displayName = "FormLayout";
FormLayout.propTypes = {
    subtitle: PropTypes.string,
    formItems: PropTypes.arrayOf(PropTypes.object),
    formData: PropTypes.object,
    projId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
    pactId: PropTypes.number,
    options: PropTypes.array,
    selectCallBack: PropTypes.objectOf(PropTypes.func), //下拉回调  切换表单
    children: PropTypes.node,
    status: PropTypes.oneOf(["view", "add", "edit", "sign"]),
    initSelect: PropTypes.bool,
    state: PropTypes.object,
    formDisabled: PropTypes.bool,
    onValuesChange: PropTypes.func,
};

export default FormLayout;
